#ifndef _WX_DRAGIMGG_H_
#define _WX_DRAGIMGG_H_

#include "wx/bitmap.h"
#include "wx/icon.h"
#include "wx/cursor.h"
#include "wx/treectrl.h"
#include "wx/listctrl.h"
#include "wx/log.h"
#include "wx/overlay.h"
#include "wx/dcmemory.h"

class wxGenericDragImage: public wxObject {
  public:
    wxGenericDragImage( const wxCursor& cursor = wxNullCursor ) {
      Init();
      Create( cursor );
    }
    wxGenericDragImage( const wxBitmap& image, const wxCursor& cursor = wxNullCursor ) {
      Init();
      Create( image, cursor );
    }
    wxGenericDragImage( const wxIcon& image, const wxCursor& cursor = wxNullCursor ) {
      Init();
      Create( image, cursor );
    }
    wxGenericDragImage( const wxString& str, const wxCursor& cursor = wxNullCursor ) {
      Init();
      Create( str, cursor );
    }
    wxDEPRECATED( wxGenericDragImage( const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( wxGenericDragImage( const wxBitmap& image, const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( wxGenericDragImage( const wxIcon& image, const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( wxGenericDragImage( const wxString& str, const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( bool Create( const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( bool Create( const wxBitmap& image, const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( bool Create( const wxIcon& image, const wxCursor& cursor, const wxPoint& cursorHotspot ) );
    wxDEPRECATED( bool Create( const wxString& str, const wxCursor& cursor, const wxPoint& cursorHotspot ) );

    #if wxUSE_TREECTRL
    wxGenericDragImage( const wxTreeCtrl& treeCtrl, wxTreeItemId& id ) {
      Init();
      Create( treeCtrl, id );
    }
    #endif

    #if wxUSE_LISTCTRL
    wxGenericDragImage( const wxListCtrl& listCtrl, long id ) {
      Init();
      Create( listCtrl, id );
    }
    #endif

    virtual ~wxGenericDragImage();

    void SetBackingBitmap( wxBitmap* bitmap ) {
      #ifndef wxHAS_NATIVE_OVERLAY
      m_pBackingBitmap = bitmap;
      #endif
    }

    bool Create( const wxCursor& cursor = wxNullCursor );
    bool Create( const wxBitmap& image, const wxCursor& cursor = wxNullCursor );
    bool Create( const wxIcon& image, const wxCursor& cursor = wxNullCursor );
    bool Create( const wxString& str, const wxCursor& cursor = wxNullCursor );

    #if wxUSE_TREECTRL
    bool Create( const wxTreeCtrl& treeCtrl, wxTreeItemId& id );
    #endif

    #if wxUSE_LISTCTRL
    bool Create( const wxListCtrl& listCtrl, long id );
    #endif

    bool BeginDrag( const wxPoint& hotspot, wxWindow* window, bool fullScreen = false, wxRect* rect = ( wxRect* ) NULL );
    bool BeginDrag( const wxPoint& hotspot, wxWindow* window, wxWindow* fullScreenRect );
    bool EndDrag();
    bool Move( const wxPoint& pt );
    bool Show();
    bool Hide();
    void Init();
    virtual wxRect GetImageRect( const wxPoint& pos ) const;
    virtual bool DoDrawImage( wxDC& dc, const wxPoint& pos ) const;
    virtual bool UpdateBackingFromWindow( wxDC& windowDC, wxMemoryDC& destDC,
                                          const wxRect& sourceRect, const wxRect& destRect ) const;
    virtual bool RedrawImage( const wxPoint& oldPos, const wxPoint& newPos, bool eraseOld, bool drawNew );
  protected:
    wxBitmap        m_bitmap;
    wxIcon          m_icon;
    wxCursor        m_cursor;
    wxCursor        m_oldCursor;
    wxPoint         m_offset;
    wxPoint         m_position;
    bool            m_isDirty;
    bool            m_isShown;
    wxWindow*       m_window;
    wxDC*           m_windowDC;

    #ifdef wxHAS_NATIVE_OVERLAY
    wxOverlay       m_overlay;
    wxDCOverlay*     m_dcOverlay;
    #else
    wxBitmap        m_backingBitmap;
    wxBitmap*       m_pBackingBitmap;
    wxBitmap        m_repairBitmap;
    #endif

    wxRect          m_boundingRect;
    bool            m_fullScreen;
  private:
    DECLARE_DYNAMIC_CLASS( wxGenericDragImage )
    DECLARE_NO_COPY_CLASS( wxGenericDragImage )
};

#endif
